home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / comm / pccp019.zip / XMCRC1KS.C < prev    next >
Text File  |  1992-05-04  |  8KB  |  411 lines

  1. /*    Copyright (C) 1992 Peter Edward Cann, all rights reserved.
  2.  *    MicroSoft QuickC
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<bios.h>
  7. #include<dos.h>
  8. #include<fcntl.h>
  9. #include<sys\types.h>
  10. #include<sys\stat.h>
  11. #include<signal.h>
  12.  
  13. #define DLLSBREG 0
  14. #define DLMSBREG 1
  15. #define INTCTLREG 1
  16. #define INTIDREG 2
  17. #define LCTLREG 3
  18. #define MCTLREG 4
  19. #define STATREG 5
  20. #define MSTATREG 6
  21.  
  22. #define CTSMASK 0x10
  23. #define TXMTMASK 0x20
  24. #define RXRDYMASK 0x01
  25.  
  26. #define INTACK 0x20
  27.  
  28. #define DB7 0x02
  29. #define DB8 0x03
  30. #define STOP2 0x04
  31. #define PARITYEN 0x08
  32. #define PARITYEVEN 0x10
  33. #define DLAB 0x80
  34.  
  35. #define INTBASE1 0x20
  36. #define INTMASK1 0x21
  37. #define INTBASE2 0xa0
  38. #define INTMASK2 0xa1
  39.  
  40. #define TBUFSIZ 256
  41.  
  42. #define NAK 21
  43. #define ACK 6
  44. #define SOH 1
  45. #define STX 2
  46. #define EOT 4
  47. #define CAN 24
  48.  
  49. int index, basereg;
  50. unsigned char buf[TBUFSIZ];
  51. unsigned char diffintmask, irqnum;
  52. void (interrupt far *oldvect)();
  53.  
  54. void interrupt far inthndl(_es, _ds, _di, _si, _bp, _sp,
  55.               _bx, _dx, _cx, _ax, _ip, _cs, _flags)
  56.     unsigned _es, _ds, _di, _si, _bp, _sp;
  57.     unsigned _bx, _dx, _cx, _ax, _ip, _cs, _flags;
  58.     {
  59.     if(inp(basereg+STATREG)&RXRDYMASK)
  60.         {
  61.         buf[index++]=inp(basereg)&0xff;
  62.         index=index%TBUFSIZ;
  63.         }
  64.     outp(INTBASE1, INTACK);
  65.     outp(INTBASE2, INTACK);
  66.     }
  67.  
  68. sendchar(c)
  69.     unsigned char c;
  70.     {
  71.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)));
  72.     outp(basereg, c);
  73.     }
  74.  
  75. int follow;
  76.  
  77. int rcharto(ticks)
  78.     int ticks;
  79.     {
  80.     long tstamp, tstamp1, dayofticksp;
  81.     int c;
  82.     _bios_timeofday(_TIME_GETCLOCK, &tstamp);
  83.     dayofticksp=0;
  84.     while(1)
  85.         {
  86.         if(_bios_timeofday(_TIME_GETCLOCK, &tstamp1))
  87.             dayofticksp+=20*60*60*24;
  88.         if(tstamp1+dayofticksp-tstamp>ticks)
  89.             return(-1); /* NOTE: This is an INT!!! */
  90.         if(follow!=index)
  91.             {
  92.             c=buf[follow++];
  93.             follow=follow%TBUFSIZ;
  94.             return(c);
  95.             }
  96.         }
  97.     }
  98.  
  99. int calccrc(ptr, count)
  100.     char *ptr;
  101.     int count;
  102.     {
  103.     int crc, i;
  104.     crc = 0;
  105.     while(--count >= 0)
  106.         {
  107.         crc = crc ^ (int)*ptr++ << 8;
  108.         for(i = 0; i < 8; ++i)
  109.             if(crc & 0x8000)
  110.                 crc = crc << 1 ^ 0x1021;
  111.             else
  112.                 crc = crc << 1;
  113.         }
  114.     return (crc & 0xFFFF);
  115.     }
  116.  
  117. unsigned char block[1024];
  118.  
  119. sblock(blockn)
  120.     int blockn;
  121.     {
  122.     unsigned char c;
  123.     unsigned short crc, rcrc;
  124.     int i;
  125.     crc=calccrc(block, 1024);
  126.     sendchar(STX);
  127.     sendchar(blockn);
  128.     sendchar((blockn^0xff)&0xff);
  129.     for(i=0;i<1024;++i)
  130.         sendchar(block[i]);
  131.     sendchar((crc>>8)&0xff);
  132.     sendchar(crc&0xff);
  133.     }
  134.  
  135. unsigned char shortblock[128];
  136.  
  137. ssblock(blockn)
  138.     int blockn;
  139.     {
  140.     unsigned char c;
  141.     unsigned short crc, rcrc;
  142.     int i;
  143.     crc=calccrc(shortblock, 128);
  144.     sendchar(SOH);
  145.     sendchar(blockn);
  146.     sendchar((blockn^0xff)&0xff);
  147.     for(i=0;i<128;++i)
  148.         sendchar(shortblock[i]);
  149.     sendchar((crc>>8)&0xff);
  150.     sendchar(crc&0xff);
  151.     }
  152.  
  153. unsigned intnum;
  154. unsigned char oldintmask;
  155.  
  156. cleanup()
  157.     {
  158.     if(intnum==10)
  159.         outp(INTMASK2, oldintmask);
  160.     else
  161.         outp(INTMASK1, oldintmask);
  162.     outp(basereg+INTCTLREG, 0x00);
  163.     outp(basereg+MCTLREG, 0x03);
  164.     _dos_setvect(intnum, oldvect);
  165.     }
  166.  
  167. quit()
  168.     {
  169.     cleanup();
  170.     exit(99);
  171.     }
  172.  
  173. main(argc, argv)
  174.     int argc;
  175.     char **argv;
  176.     {
  177.     int i, j, k, l, infd, ok, c;
  178.     unsigned char *blkptr;
  179.     unsigned char newintmask, lctl, dlmsb, dllsb, blocknum;
  180.     long nbytes;
  181.     unsigned speed;
  182.     int comnum;
  183.     char stopbits;
  184.     index=follow=0;
  185.     lctl=0;
  186.     printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  187.     printf("xmodem crc 1k send of %s.\n", argv[4]);
  188.     if(argc!=5)
  189.         {
  190.         printf("USAGE: xmodemr <comnum> <bps> <stopbits> <file pathname>\n");
  191.         exit(1);
  192.         }
  193.     if((infd=open(argv[4], O_RDONLY|O_BINARY))==-1)
  194.         {
  195.         printf("Error opening file %s.\n", argv[4]);
  196.         exit(2);
  197.         }
  198.     comnum=atoi(argv[1])-1;
  199.     newintmask=0;
  200.     switch(comnum)
  201.         {
  202.         case 0:
  203.             irqnum=4;
  204.             diffintmask=0xff&~0x10;
  205.             basereg=0x3f8;
  206.             break;
  207.         case 1:
  208.             irqnum=3;
  209.             diffintmask=0xff&~0x08;
  210.             basereg=0x2f8;
  211.             break;
  212.         case 2:
  213.             irqnum=4;
  214.             diffintmask=0xff&~0x10;
  215.             basereg=0x3e8;
  216.             break;
  217.         case 3:
  218.             irqnum=3;
  219.             diffintmask=0xff&~0x08;
  220.             basereg=0x2e8;
  221.             break;
  222.         case 4:
  223.             irqnum=2;
  224.             diffintmask=0xff&~0x02;
  225.             basereg=0x3e8;
  226.             break;
  227.         case 5:
  228.             irqnum=2;
  229.             diffintmask=0xff&~0x02;
  230.             basereg=0x2e8;
  231.             break;
  232.         case 6:
  233.             irqnum=5;
  234.             diffintmask=0xff&~0x20;
  235.             basereg=0x3e8;
  236.             break;
  237.         case 7:
  238.             irqnum=5;
  239.             diffintmask=0xff&~0x20;
  240.             basereg=0x2e8;
  241.             break;
  242.         default:
  243.             printf("Bad port choice.\n");
  244.             exit(4);
  245.         }
  246.     intnum=irqnum+8;
  247.     speed=atoi(argv[2]);
  248.     switch(speed)
  249.         {
  250.         case 300:
  251.             dlmsb=0;
  252.             dllsb=0xc0;
  253.             break;
  254.         case 1200:
  255.             dlmsb=0;
  256.             dllsb=0x60;
  257.             break;
  258.         case 2400:
  259.             dlmsb=0;
  260.             dllsb=0x30;
  261.             break;
  262.         case 9600:
  263.             dlmsb=0;
  264.             dllsb=0x0c;
  265.             break;
  266.         case 19200:
  267.             dlmsb=0;
  268.             dllsb=0x06;
  269.             break;
  270.         case 38400:
  271.             dlmsb=0;
  272.             dllsb=0x03;
  273.             break;
  274.         case 57600:
  275.             dlmsb=0;
  276.             dllsb=0x02;
  277.             break;
  278.         default:
  279.             printf("Bad speed.\n");
  280.             exit(5);
  281.         }
  282.     lctl|=DB8;
  283.     stopbits=argv[3][0];
  284.     switch(stopbits)
  285.         {
  286.         case '1':
  287.             break;
  288.         case '2':
  289.             lctl|=STOP2;
  290.             break;
  291.         default:
  292.             printf("Bad stop bits.\n");
  293.             exit(9);
  294.         }
  295.     signal(SIGINT, quit);
  296.     outp(basereg+LCTLREG, DLAB);
  297.     outp(basereg+DLLSBREG, dllsb);
  298.     outp(basereg+DLMSBREG, dlmsb);
  299.     outp(basereg+LCTLREG, lctl);
  300.     oldvect=_dos_getvect(intnum);
  301.     _dos_setvect(intnum, inthndl);
  302.     outp(basereg+INTCTLREG, 0x00);
  303.     outp(basereg+MCTLREG, 0x0b);
  304.     oldintmask=(intnum==10)?inp(INTMASK2):inp(INTMASK1);
  305.     newintmask=diffintmask;
  306.     newintmask&=oldintmask;
  307.     if(intnum==10)
  308.         outp(INTMASK2, newintmask);
  309.     else
  310.         outp(INTMASK1, newintmask);
  311.     outp(INTBASE1, INTACK);
  312.     outp(INTBASE2, INTACK);
  313.     outp(basereg+INTCTLREG, 0x01);
  314.     outp(INTBASE1, INTACK);
  315.     outp(INTBASE2, INTACK);
  316.     nbytes=0;
  317.     if(rcharto(2000)!='C')
  318.         {
  319.         printf("Spurrious char or no C in 100 seconds.\n");
  320.         cleanup();
  321.         exit(10);
  322.         }
  323.     blocknum=1;
  324.     while(1)
  325.         {
  326.         if((j=read(infd, block, 1024))==0)
  327.             {
  328.             printf("\nEnd of file.\n");
  329.             sendchar(EOT);
  330.             do
  331.                 c=rcharto(300);
  332.             while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  333.             if(c!=ACK)
  334.                 {
  335.                 printf("No ACK of EOT.\n");
  336.                 cleanup();
  337.                 exit(13);
  338.                 }
  339.             else
  340.                 {
  341.                 printf("Successful.\n");
  342.                 cleanup();
  343.                 exit(0);
  344.                 }
  345.             }
  346.         for(c=j;c<1024;c++)
  347.             block[c]=26;
  348.         if(j>896)
  349.             {
  350.             i=0;
  351.             do
  352.                 {
  353.                 printf("\nSending block %d. ", blocknum);
  354.                 sblock(blocknum);
  355.                 do
  356.                     c=rcharto(200);
  357.                 while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  358.                 }
  359.             while((c==NAK)&&(i++<10));
  360.             if(c==ACK)
  361.                 {
  362.                 blocknum++;
  363.                 nbytes+=1024;
  364.                 printf("Successful. Bytes so far: %ld", nbytes);
  365.                 }
  366.             }
  367.         else
  368.             {
  369.             for(k=0;k<(j+128);k+=128)
  370.                 {
  371.                 i=0;
  372.                 do
  373.                     {
  374.                     for(l=0;l<128;++l)
  375.                         shortblock[l]=block[k+l];
  376.                     printf("\nSending block %d. ", blocknum);
  377.                     ssblock(blocknum);
  378.                     do
  379.                         c=rcharto(200);
  380.                     while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  381.                     }
  382.                 while((c==NAK)&&(i++<10));
  383.                 if(c!=ACK)
  384.                     break;
  385.                 else
  386.                     {
  387.                     blocknum++;
  388.                     nbytes+=128;
  389.                     printf("Successful. Bytes so far: %ld", nbytes);
  390.                     }
  391.                 }
  392.             }
  393.         if(c!=ACK)
  394.             if(c==NAK)
  395.                 {
  396.                 printf("\nRetry limit exceeded.\n");
  397.                 cleanup();
  398.                 exit(14);
  399.                 }
  400.             else
  401.                 {
  402.                 printf("\nSpurrious character hex %02x; ACK or NAK expected.\n", c);
  403.                 cleanup();
  404.                 exit(11);
  405.                 }
  406.         }
  407.     printf("Programming error; fell through end; see code.\n");
  408.     cleanup();
  409.     exit(12);
  410.     }
  411.